package com.libleveldb

import com.libleveldb.exception.LevelDBClosedException
import com.libleveldb.exception.LevelDBIteratorNotValidException
import java.io.Closeable

abstract class Iterator : Closeable {
    /**
     * Checks if there is a key-value pair over the current position of the iterator.
     *
     * @throws LevelDBClosedException
     */
    @get:Throws(LevelDBClosedException::class)
    abstract val isValid: Boolean

    /**
     * Moves to the first key-value pair in the database.
     *
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBClosedException::class)
    abstract fun seekToFirst()

    /**
     * Moves to the last key-value pair in the database.
     *
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBClosedException::class)
    abstract fun seekToLast()

    /**
     * Moves on top of, or just after key, in the database.
     *
     * @param key the key to seek, if null throws an [java.lang.IllegalArgumentException]
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBClosedException::class)
    abstract fun seek(key: ByteArray?)

    /**
     * Moves to the next entry in the database.
     *
     * @throws LevelDBIteratorNotValidException if not [.isValid]
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBIteratorNotValidException::class, LevelDBClosedException::class)
    abstract operator fun next()

    /**
     * Moves to the previous entry in the database.
     *
     * @throws LevelDBIteratorNotValidException if not [.isValid]
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBIteratorNotValidException::class, LevelDBClosedException::class)
    abstract fun previous()

    /**
     * Returns the key under the iterator.
     *
     * @return the key
     * @throws LevelDBIteratorNotValidException if not [.isValid]
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBIteratorNotValidException::class, LevelDBClosedException::class)
    abstract fun key(): ByteArray?

    /**
     * Returns the value under the iterator.
     *
     * @return the value
     * @throws LevelDBIteratorNotValidException if not [.isValid]
     * @throws LevelDBClosedException
     */
    @Throws(LevelDBClosedException::class)
    abstract fun value(): ByteArray?

    /**
     * Checks whether this iterator has been closed.
     */
    abstract val isClosed: Boolean

    /**
     * Closes this iterator if it has not been. It is usually unusable after a call to this method.
     */
    abstract override fun close()
}